﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SettingsFilesTree.cs" company="Roman '4ux-nbIx' Novitsky">
//   Copyright (c) Roman '4ux-nbIx' Novitsky 2009
// </copyright>
// <summary>
//   Describes and manipulates the settings files list.
// </summary>
// --------------------------------------------------------------------------------------------------------------------


namespace SettingsManager
{
    #region Namespace Imports

    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;

    #endregion


    /// <summary>
    /// Describes and manipulates the settings files list.
    /// </summary>
    internal sealed partial class SettingsFilesTree : UserControl
    {
        #region Constants and Fields

        private readonly TreeNode _personalFilesNode;
        private readonly TreeNode _sharedFilesNode;
        private ResharperSettingsManager _settingsManager;
        private SolutionSettingsManager _solutionSettingsManager;

        #endregion


        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="SettingsFilesTree"/> class.
        /// </summary>
        public SettingsFilesTree()
        {
            InitializeComponent();

            _personalFilesNode = _listBox.Nodes[0];
            _sharedFilesNode = _listBox.Nodes[1];

            RefreshPersonalFilesList();
            RefreshSharedFilesList();
        }

        #endregion


        #region Delegates

        private delegate void ListRefreshDelegate();

        #endregion


        #region Events

        /// <summary>
        /// Occurs when selected item index has changed.
        /// </summary>
        public event EventHandler SelectedIndexChanged;

        #endregion


        #region Properties

        /// <summary>
        /// Gets the selected item.
        /// </summary>
        /// <value>
        /// The selected item.
        /// </value>
        public SettingsFile SelectedItem
        {
            get
            {
                if (_listBox.SelectedNode != null)
                {
                    return _listBox.SelectedNode.Tag as SettingsFile;
                }

                return null;
            }
        }

        /// <summary>
        /// Gets or sets the settings manager.
        /// </summary>
        /// <value>
        /// The settings manager.
        /// </value>
        public ResharperSettingsManager SettingsManager
        {
            get
            {
                return _settingsManager;
            }

            set
            {
                if (_settingsManager != null)
                {
                    _settingsManager.SettingsFileListChanged -= OnSettingsManagerSettingsFileListChanged;
                }

                _settingsManager = value;

                if (_settingsManager != null)
                {
                    _settingsManager.SettingsFileListChanged += OnSettingsManagerSettingsFileListChanged;
                }

                RefreshPersonalFilesList();
            }
        }


        /// <summary>
        /// Gets or sets the solution settings manager.
        /// </summary>
        /// <value>
        /// The solution settings manager.
        /// </value>
        public SolutionSettingsManager SolutionSettingsManager
        {
            get
            {
                return _solutionSettingsManager;
            }

            set
            {
                if (_solutionSettingsManager != null)
                {
                    _solutionSettingsManager.SharedSettingsChanged -= OnSolutionSettingsManagerSharedSettingsChanged;
                }

                _solutionSettingsManager = value;

                if (_solutionSettingsManager != null)
                {
                    _solutionSettingsManager.SharedSettingsChanged += OnSolutionSettingsManagerSharedSettingsChanged;
                }

                RefreshSharedFilesList();
            }
        }

        #endregion


        #region Methods

        private void OnSettingsManagerSettingsFileListChanged(object sender, EventArgs e)
        {
            try
            {
                ListRefreshDelegate refreshDelegate = RefreshPersonalFilesList;
                Invoke(refreshDelegate);
            }
            catch
            {
                return;
            }
        }


        private void OnSolutionSettingsManagerSharedSettingsChanged(object sender, EventArgs e)
        {
            try
            {
                ListRefreshDelegate refreshDelegate = RefreshSharedFilesList;
                Invoke(refreshDelegate);
            }
            catch
            {
                return;
            }
        }


        private void OnTreeViewAfterSelect(object sender, EventArgs e)
        {
            if (SelectedIndexChanged != null)
            {
                SelectedIndexChanged(this, EventArgs.Empty);
            }
        }


        /// <summary>
        /// Refreshes the list.
        /// </summary>
        private void RefreshPersonalFilesList()
        {
            _personalFilesNode.Nodes.Clear();

            if (_settingsManager != null)
            {
                if (!_settingsManager.IsSettingsFolderValid)
                {
                    var node = new TreeNode("The settings folder is either not configured, or doesn't exist. Please check RSM settings.", 7, 7);
                    _personalFilesNode.Nodes.Add(node);
                }
                else
                {
                    IEnumerable<SettingsFile> settingsFiles = _settingsManager.SettingsFiles;

                    foreach (SettingsFile file in settingsFiles)
                    {
                        var node = new SettingsFileTreeNode(file);
                        _personalFilesNode.Nodes.Add(node);
                    }

                    if (_sharedFilesNode.Nodes.Count == 0)
                    {
                        var node = new TreeNode("No settings files found.", 5, 5);
                        _personalFilesNode.Nodes.Add(node);
                    }
                }
            }

            OnTreeViewAfterSelect(this, EventArgs.Empty);
        }


        /// <summary>
        /// Refreshes the list.
        /// </summary>
        private void RefreshSharedFilesList()
        {
            _sharedFilesNode.Nodes.Clear();

            if (_solutionSettingsManager != null)
            {
                SharedSettingsFile sharedSettingsFile = _solutionSettingsManager.SharedSettingsFile;
                var settingsFiles = new List<SettingsFile>();

                while (sharedSettingsFile != null)
                {
                    settingsFiles.Insert(0, sharedSettingsFile);
                    sharedSettingsFile = sharedSettingsFile.ParentSettingsFile;
                }

                foreach (SettingsFile file in settingsFiles)
                {
                    var node = new SettingsFileTreeNode(file);
                    _sharedFilesNode.Nodes.Add(node);
                }

                if (_sharedFilesNode.Nodes.Count == 0)
                {
                    var node = new TreeNode("No shared settings files found.", 5, 5);
                    _sharedFilesNode.Nodes.Add(node);
                }
            }
            else
            {
                var node = new TreeNode("No solution loaded.", 5, 5);
                _sharedFilesNode.Nodes.Add(node);
            }

            OnTreeViewAfterSelect(this, EventArgs.Empty);
        }

        #endregion
    }
}